#define _CRT_SECURE_NO_WANINGS 1
#pragma warning(disable: 4996)
#include<stdlib.h>



typedef struct MyCircularQueue {
    struct MyCircularQueue* prev;
    struct MyCircularQueue* next;
    int val;
    int k;
} MyCircularQueue;


MyCircularQueue* myCircularQueueCreate(int k) {
    MyCircularQueue* phead = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    phead->next = phead;
    phead->prev = phead;
    phead->val = -1;
    phead->k = k;
    return phead;
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
    if (obj->next == obj)
    {
        return true;
    }
    return false;
}

bool myCircularQueueIsFull(MyCircularQueue* obj) {
    MyCircularQueue* cur = obj->next;
    int size = 0;
    while (cur != obj)
    {
        cur = cur->next;
        size++;
    }
    return size == obj->k;
}
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
    if (myCircularQueueIsFull(obj))
    {
        return false;
    }
    MyCircularQueue* newnode = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    if (newnode == NULL)
    {
        perror("malloc failed");
        exit(-1);
    }
    newnode->val = value;
    MyCircularQueue* prev = obj->prev;
    newnode->prev = prev;
    newnode->next = obj;
    prev->next = newnode;
    obj->prev = newnode;
    return true;
}

bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    if (myCircularQueueIsEmpty(obj))
    {
        return false;
    }
    MyCircularQueue* Next = obj->next;
    obj->next = Next->next;
    Next->next->prev = obj;
    free(Next);
    Next = NULL;
    return true;
}

int myCircularQueueFront(MyCircularQueue* obj) {
    if (myCircularQueueIsEmpty(obj))
    {
        return -1;
    }
    return obj->next->val;
}

int myCircularQueueRear(MyCircularQueue* obj) {
    if (myCircularQueueIsEmpty(obj))
    {
        return -1;
    }
    return obj->prev->val;
}



void myCircularQueueFree(MyCircularQueue* obj) {
    MyCircularQueue* cur = obj->next;
    while (cur != obj)
    {
        MyCircularQueue* del = cur;
        cur = cur->next;
        free(del);
        del = NULL;
    }
    free(obj);
    obj = NULL;
}
int main()
{
    MyCircularQueue* obj = myCircularQueueCreate(3);
    
    myCircularQueueEnQueue(obj, 1);
    myCircularQueueEnQueue(obj, 2);
    myCircularQueueEnQueue(obj, 3);
    myCircularQueueEnQueue(obj, 4);
    myCircularQueueDeQueue(obj);
    myCircularQueueEnQueue(obj,4);
    return 0;
}

/**
 * Your MyCircularQueue struct will be instantiated and called as such:
 * MyCircularQueue* obj = myCircularQueueCreate(k);
 * bool param_1 = myCircularQueueEnQueue(obj, value);

 * bool param_2 = myCircularQueueDeQueue(obj);

 * int param_3 = myCircularQueueFront(obj);

 * int param_4 = myCircularQueueRear(obj);

 * bool param_5 = myCircularQueueIsEmpty(obj);

 * bool param_6 = myCircularQueueIsFull(obj);

 * myCircularQueueFree(obj);
*/